/** @file

  Copyright (C) 2022 - 2023, Phytium Technology Co., Ltd. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#ifndef _PARAMETER_H
#define _PARAMETER_H

#include <Library/BaseMemoryLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Uefi/UefiBaseType.h>
//#define USE_PARAMETER		//采用读取参数表

#define O_PARAMETER_BASE            0xA0000 /*640k*/

#define PM_PLL_OFFSET               (0x0)
#define PM_PCIE_OFFSET              (0x100)
#define PM_COMMON_OFFSET            (0x200)
#define PM_DDR_OFFSET               (0x300)
#define PM_BOARD_OFFSET             (0x400)
#define PM_SECURE_OFFSET            (0x500)

#define PARAMETER_PLL_MAGIC                 0x54460010
#define PARAMETER_PCIE_MAGIC                0x54460011
#define PARAMETER_COMMON_MAGIC              0x54460013
#define PARAMETER_DDR_MAGIC                 0x54460014
#define PARAMETER_BOARD_MAGIC               0x54460015

#define PM_PLL		0
#define PM_PCIE		1
#define PM_COMMON	2
#define PM_DDR		3
#define PM_BOARD    4

#define PM_GPIO  0
#define PM_EC    1
#define PM_SE    2

#define PEU1_SPLITMODE_OFFSET 16
#define PEU0_SPLITMODE_OFFSET 0

#define SPEED_OFFSET 0
#define ENABLE_OFFSET 9



typedef struct {
  UINT8  CharacteristicsUnknown;
  UINT8  Provides50Volts;
  UINT8  Provides33Volts;
  UINT8  SharedSlot;
  UINT8  PcCard16Supported;
  UINT8  CardBusSupported;
  UINT8  ZoomVideoSupported;
  UINT8  ModemRingResumeSupported;
}SlotCharacteristics1;

typedef struct {
  UINT8  PmeSignalSupported;
  UINT8  HotPlugDevicesSupported;
  UINT8  SmbusSignalSupported;
  UINT8  BifurcationSupported;
  UINT8  Reserved[4];///< Set to 0.
}SlotCharacteristics2;

typedef struct {
  UINT8  GenNumber;
  UINT8  Xnumber;
  UINT8  SlotType;
  UINT8  SlotDataBusWidth;

  UINT8  CurrentUsage;
  UINT8  SlotLength;
  UINT16 Res;
  SlotCharacteristics1  SlotChara1;
  SlotCharacteristics2  SlotChara2;

  UINT16 SlotID;
  UINT16 SegmentGroupNum;

  UINT8  BusNum;
  UINT8  DevFuncNum;
  UINT8  DataBusWidth;
  UINT8  PeerGroupingCount;
}PCIE_INFO;
typedef struct {
  UINT8      SlotsNumber;
  UINT8      Res[3];
  PCIE_INFO  PcieInfo[6];
}SYSTEM_SLOTS;

typedef struct {
  UINT8  Size;//GB
  UINT8  FormFactor;//enum
  UINT8  ChannelNumer;//0 or 1
  UINT8  DimmNumer;//0 or 1

  UINT8  MemoryType;
  UINT8  RankNumber;//Attributes
  UINT16 DeviceSet;//0

  //CHAR8  Manufacturer[10];//send id
  UINT32  SerialNumber;
  //CHAR8  AssertTag;
  //CHAR8  PartNumber;
  UINT32 ExtendedSize;

  UINT16 Speed;//MT
  UINT16 ConfiguredMemorySpeed;//MT

  UINT16 MinVoltage;//mv
  UINT16 MaxVoltage;//mv

  UINT16 ConfiguredVoltage;//mv
  //CHAR8  FirmwareVersion;
  UINT16 ModuleManufacturerID;

  UINT16 ModuleProductID;
  UINT16 MemorSubsystemControllerManufacturerID;

  UINT16 MemorSubsystemControllerProductID;
  UINT16 Manufacturer;//send id

  UINT8  MemoryTechnology;
  UINT8  Reserve[3];

  CHAR8  PartNumber[21];
  UINT8  Reserve2[3];
}SPD_INFO;

typedef struct {
  UINT8     DevicesNumber;//actual ddr number
  UINT8     DimmCount;//toal dimm count
  UINT16    Reserve;
  SPD_INFO  SpdInfo[4];//spd information
}MEMORY_DEVICES_INFO;

typedef struct {
    UINT32 Magic;
    UINT32 Version;
    UINT32 Size;
    UINT8  Rev1[4];
}__attribute__((aligned(sizeof(UINT64)))) PARAMETER_HEADER;



typedef struct secure_config {
    UINT64       misc_enable;  //0: tzc en; 1: aes en

    UINT64  tzc_region_low_1;  //tzc enable时,开放4个安全域供用户配置
    UINT64  tzc_region_top_1;
    UINT64  tzc_region_low_2;
    UINT64  tzc_region_top_2;
    UINT64  tzc_region_low_3;
    UINT64  tzc_region_top_3;
    UINT64  tzc_region_low_4;
    UINT64  tzc_region_top_4;
}__attribute__((aligned(sizeof(unsigned long)))) SECURE_CONFIG_T;

static SECURE_CONFIG_T const SECURE_BASE_INFO = {
    .misc_enable   = 0x0,
};

/*-------------------PLL------------------*/
typedef struct {
  PARAMETER_HEADER Head;
  UINT32 CoreFrequency;
  UINT32 Res1;
  UINT32 DdrFrequency;
  UINT32 Res2;
  UINT32 Res3;
  UINT32 Res4;
  UINT32 Res5;
}__attribute__((aligned(sizeof(UINT64)))) PLL_CONFIG;

/*-------------------PEU------------------*/
//typedef struct {
  //UINT32 ControllerConfig[3];
  //UINT32 ControllerEqualization[3];
  //UINT8  Rev[80];
//}__attribute__((aligned(sizeof(UINT64)))) PEU_FEATURES_CONFIG;

typedef struct {
  PARAMETER_HEADER Head;
  UINT32 IndependentTree;
  UINT32 FunctionConfig;
  UINT8  Rev0[16];
  UINT32 Peu0ControllerConfig[3];
  UINT32 Peu0ControllerEqualization[3];
  UINT8  Rev1[80];
  UINT32 Peu1ControllerConfig[3];
  UINT32 Peu1ControllerEqualization[3];
}__attribute__((aligned(sizeof(UINT64)))) PARAMETER_PEU_CONFIG;

/*-------------------COMMON------------------*/
typedef struct {
  PARAMETER_HEADER Head;
  UINTN CoreBitMap;
}__attribute__((aligned(sizeof(UINT64)))) COMMON_CONFIG;

/*-------------------MCU------------------*/
typedef struct {
  /******************* read from spd *****************/
  UINT8  dimm_type;     /* 1: RDIMM;2: UDIMM;3: SODIMM;4: LRDIMM */
  UINT8  data_width;    /* 0: x4; 1: x8; 2: x16 */
  UINT8  mirror_type;   /* 0: stardard; 1: mirror */
  UINT8  ecc_type;      /* 0: no-ecc; 1:ecc */
  UINT8  dram_type;     /* 0xB: DDR3; 0xC: DDR4 */
  UINT8  rank_num;
  UINT8  row_num;
  UINT8  col_num;

  UINT8  bg_num;		  /*only DDR4*/
  UINT8  bank_num;
  UINT16 module_manufacturer_id;
  UINT16 tAAmin;
  UINT16 tRCDmin;

  UINT16 tRPmin;
  UINT16 tRASmin;
  UINT16 tRCmin;
  UINT16 tFAWmin;

  UINT16 tRRD_Smin;		/*only DDR4*/
  UINT16 tRRD_Lmin;		/*only DDR4*/
  UINT16 tCCD_Lmin;		/*only DDR4*/
  UINT16 tWRmin;

  UINT16 tWTR_Smin;		/*only DDR4*/
  UINT16 tWTR_Lmin;		/*only DDR4*/
  UINT16 tWTRmin;		    /*only DDR3*/
  UINT16 tRRDmin;		    /*only DDR3*/

  /******************* RCD control words *****************/
  UINT8  F0RC03; /*bit[3:2]:CS         bit[1:0]:CA  */
  UINT8  F0RC04; /*bit[3:2]:ODT        bit[1:0]:CKE */
  UINT8  F0RC05; /*bit[3:2]:CLK-A side bit[1:0]:CLK-B side */
  UINT8  BC00;
  UINT8  BC01;
  UINT8  BC02;
  UINT8  BC03;
  UINT8  BC04;

  UINT8  BC05;
  UINT8  F5BC5x;
  UINT8  F5BC6x;
  /**************** LRDIMM special *****************/
  UINT8  vrefDQ_PR0;     /*Byte 140 (0x08C) (Load Reduced): DRAM VrefDQ for Package Rank 0*/
  UINT8  vrefDQ_MDRAM;   /* Byte 144 (0x090) (Load Reduced): Data Buffer VrefDQ for DRAM Interface*/
  UINT8  RTT_MDRAM_1866; /*Byte 145 (0x091) (Load Reduced): Data Buffer MDQ Drive Strength and RTT for data rate < 1866 */
  UINT8  RTT_MDRAM_2400; /*Byte 146 (0x092) (Load Reduced): Data Buffer MDQ Drive Strength and RTT for 1866<datarate<2400 */
  UINT8  RTT_MDRAM_3200; /*Byte 147 (0x093) (Load Reduced): Data Buffer MDQ Drive Strength and RTT for 2400<datarate<3200 */

  UINT8  Drive_DRAM;     /*Byte 148 (0x094) (Load Reduced): DRAM Drive Strength */
  UINT8  ODT_DRAM_1866;  /* Byte 149 (0x095) (Load Reduced): DRAM ODT (RTT_WR and RTT_NOM) for data rate < 1866 */
  UINT8  ODT_DRAM_2400;  /* Byte 150 (0x096) (Load Reduced): DRAM ODT (RTT_WR and RTT_NOM) for 1866 < data rate < 2400 */
  UINT8  ODT_DRAM_3200;  /* Byte 151 (0x097) (Load Reduced): DRAM ODT (RTT_WR and RTT_NOM) for 2400 < data rate < 3200 */
  UINT8  PARK_DRAM_1866; /* Byte 152 (0x098) (Load Reduced): DRAM ODT (RTT_PARK) for data rate < 1866 */
  UINT8  PARK_DRAM_2400; /* Byte 153 (0x099) (Load Reduced): DRAM ODT (RTT_PARK) for 1866 < data rate < 2400 */
  UINT8  PARK_DRAM_3200; /* Byte 154 (0x09A) (Load Reduced): DRAM ODT (RTT_PARK) for 2400 < data rate  < 3200 */
  UINT8  rcd_num;        /* Registers used on RDIMM */
}__attribute__((aligned(sizeof(UINT64)))) DDR_SPD_INFO;

typedef struct {
  PARAMETER_HEADER Head;
  UINT8 ChannelEnable;
  UINT8 EccEnable;
  UINT8 DmEnable;
  UINT8 ForceSpdEnable;
  UINT8 MiscEnable;	/*0:read spd req 1:use margin 2: s3 back devinit 3: cmd 2T mode 4:dual dimm*/
  UINT8 TrainDebug;
  UINT8 TrainRecover;
  UINT8 Rev2[9];
  DDR_SPD_INFO DdrSpdInfo[2];
}__attribute__((aligned(sizeof(UINT64)))) DDR_CONFIG;

typedef struct {
  PARAMETER_HEADER Head;
  UINT8  Misc;
  UINT8  PowerManger;
  UINT8  QspiFrequence;
}__attribute__((aligned(sizeof(unsigned long)))) BOARD_CONFIG;


EFI_STATUS GetParameterInfo(UINT32 Id, UINT8 *Data, UINT32 DataSize);
#endif
